/*    
    OpenMheg - A free MHEG-5 library
    Copyright (C) 2008 Dharmesh Malam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Core.Model.Data;
using Core.Model.Ingredients.Presentable.Visibles;
using Parser;

namespace XMHEGDecoder.Builders.Visibles
{
    public class TextBuilder
    {
        public static Text Build ( XmlElement node )
        {
            Text text = new Text();
            Build( node, text );

            return text;
        }

        public static void Build ( XmlElement node, Text text )
        {
            VisibleBuilder.Build( node, text );

            #region  Add our attributes
            XmlElement e;

            e = node ["original-font"];
            if ( e != null )
                text.OriginalFont = new OctetString(DecodeUtils.DecodeBase64( e.InnerText ));

            e = node ["font-attributes"];
            if ( e != null )
                text.OriginalFontAttributes = FontAttributesBuilder( e );

            e = node ["text-colour"];
            if ( e != null )
                text.OriginalTextColour = ColourBuilder.Build( e );

            e = node ["background-colour"];
            if ( e != null )
                text.OriginalBackgroundColour = ColourBuilder.Build( e );

            e = node ["character-set"];
            if ( e != null )
                text.CharacterSet = DecodeUtils.ParseInt( e.InnerText );

            e = node ["horizontal-justification"];
            if ( e != null )
                text.HorizontalJustification = ParseJustification( e );

            e = node ["vertical-justification"];
            if ( e != null )
                text.VerticalJustification = ParseJustification( e );

            e = node ["line-orientation"];
            if ( e != null )
                text.LineOrientation = ParseOrientation( e );

            e = node ["start-corner"];
            if ( e != null )
                text.StartCorner = ParseStartCorner( e );

            e = node ["text-wrapping"];
            if ( e != null )
                text.TextWrapping = DecodeUtils.ParseBool( e.InnerText );
            #endregion
        }

        public static FontAttributes FontAttributesBuilder ( XmlElement node )
        {
            FontAttributes fontAttributes = new FontAttributes();
            String attributes = DecodeUtils.DecodeBase64( node.InnerText );
            String [] fields = attributes.Split( '.' );

            byte [] bytes = Convert.FromBase64String( node.InnerText );

            if ( fields.Length == 4 || fields.Length == 5)
            {

                if ( fields [0] != "plain" )
                    throw new Exception( "1.06 only allows plain" );

                fontAttributes.FontStyle = System.Drawing.FontStyle.Regular;

                int fontSize;
                if ( !int.TryParse( fields [1], out fontSize ) )
                    fontSize = Engine.MHEGConstants.DefaultFontSize;

                fontAttributes.FontSize = fontSize;


                //fontAttributes = new System.Drawing.Font(
                //                    MHEGConstants.DefaultFontName,
                //                    fontSize-12,
                //                   System.Drawing.FontStyle.Regular
                //                   );

                int lineSpacing;
                if ( !int.TryParse( fields [2], out lineSpacing ) )
                    lineSpacing = Engine.MHEGConstants.DefaultLineSpacing;

                fontAttributes.LineSpacing = lineSpacing;

                int letterSpace;
                if ( !int.TryParse( fields [3], out letterSpace ) )
                    letterSpace = Engine.MHEGConstants.DefaultLetterSpace;

                fontAttributes.LetterSpace = letterSpace;


            }

            else if ( bytes.Length == 5 )
            {

                int fontStyle;
                try
                {
                    fontStyle = ( int ) bytes [0];
                }
                catch ( Exception e )
                {
                    fontStyle = 0;
                }
                //need to reset bits 4-7
                //bit 2 is underline, bit 3 is outline
                System.Drawing.FontStyle style = System.Drawing.FontStyle.Regular;

                fontStyle &= 0xF;

                if ( ( fontStyle & 0x1 ) == 1 )
                    style |= System.Drawing.FontStyle.Italic;

                if ( ( fontStyle & 0x2 ) == 1 )
                    style |= System.Drawing.FontStyle.Bold;

                if ( ( fontStyle & 0x4 ) == 1 )
                    style |= System.Drawing.FontStyle.Underline;

                if ( ( fontStyle & 0x8 ) == 1 )
                    style |= System.Drawing.FontStyle.Strikeout;

                fontAttributes.FontStyle = style;

                int fontSize;
                // try
                // {
                fontSize = ( int ) bytes [1];
                // }
                // catch ( Exception e )
                //  {
                //      fontSize = MHEGConstants.DefaultFontSize;
                //  }
                //  finally
                //  {
                fontAttributes.FontSize = fontSize;
                // }

                //fontAttributes = new System.Drawing.Font(
                //                    MHEGConstants.DefaultFontName,
                //                    fontSize-12,
                //                    style);

                int lineSpacing;
                // try
                // {
                lineSpacing = ( int ) bytes [2];
                // }
                // catch ( Exception e )
                // {
                //     lineSpacing = MHEGConstants.DefaultLineSpacing;
                // }
                // finally
                // {
                //if ( lineSpacing != 28 ) throw new Exception( "oi" );
                fontAttributes.LineSpacing = lineSpacing;
                // }

                int letterSpace;
                // try
                // {
                letterSpace = (int) (((ushort) bytes[3] << 8) | (ushort) bytes[4]);
                    //( ( ( int ) bytes [3] << 8 ) + ( int ) bytes [4] ); //- 0x7fff;
                // }
                // catch ( Exception e )
                // {
                //     letterSpace = MHEGConstants.DefaultLetterSpace;
                // }
                // finally
                // {
                fontAttributes.LetterSpace = letterSpace;
                // }

            }
            else throw new Exception( "Can't Decode fontattribute" );

            return fontAttributes;

        }



        private static Text.TextStartCorner ParseStartCorner ( XmlElement node )
        {
            //  try
            //  {
            return ( Text.TextStartCorner ) int.Parse( node.InnerText );
            //  }
            //  catch ( FormatException e )
            //  {
            //      return Text.TextStartCorner.UpperLeft;
            //  }

        }

        private static Text.TextOrientation ParseOrientation ( XmlElement node )
        {
            // try
            // {
            return ( Text.TextOrientation ) int.Parse( node.InnerText );

            // }
            // catch ( FormatException e )
            // {
            //     return Text.TextOrientation.Horizontal;
            // }
        }

        private static Text.TextJustification ParseJustification ( XmlElement node )
        {
            // try
            // {
            return ( Text.TextJustification ) int.Parse( node.InnerText );
            //}
            //catch ( FormatException e )
            //{
            //    return Text.TextJustification.Start;
            //}
        }
    }
}
